package com.ftg.learn.chapter04.util;

import com.mysql.cj.jdbc.MysqlDataSource;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.util.Objects;

/**
 * 通用
 *
 * @author kangjx
 * @date 2024/1/29
 */
public class MybatisUtil<T> {


    private final String[] xmlNames;

    private SqlSession sqlSession;

    public MybatisUtil(String... xmlNames){
        this.xmlNames = xmlNames;
    }

    /**
     * 创建数据源
     */
    public DataSource initDataSource() {
        MysqlDataSource dataSource = new MysqlDataSource();
        dataSource.setURL("jdbc:mysql://localhost:3306/db2309");
        dataSource.setUser("root");
        dataSource.setPassword("123456");
        return dataSource;
    }

    /**
     * 创建配置
     * @return Configuration
     */
    public Configuration initConfiguration() {

        Configuration config  = new Configuration();

        TransactionFactory transactionFactory = new JdbcTransactionFactory();

        Environment e = new Environment("mysql",transactionFactory,this.initDataSource());

        config.setEnvironment(e);

        config.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);


        this.initXmlBuilder(config);

        return config;

    }

    /**
     *
     * @param config
     */
    private void initXmlBuilder(Configuration config){

        if(this.xmlNames == null){
            throw new RuntimeException("xmlNames is null");
        }

        for (String path : this.xmlNames) {
            InputStream inputStream = getClass().getClassLoader().getResourceAsStream(path);
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(inputStream, config, path,config.getSqlFragments());
            xmlMapperBuilder.parse();
        }
    }

    /**
     * 创建工厂
     * @return SqlSessionFactory
     */
    public SqlSessionFactory initSqlSessionFactory() {
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory build = sqlSessionFactoryBuilder.build(this.initConfiguration());
        return build;
    }

    /**
     * 创建SqlSession
     * @return SqlSession
     */
    public SqlSession getSqlSession() {

        if(Objects.isNull(sqlSession)){
            this.sqlSession = this.initSqlSessionFactory().openSession();
        }
        return this.sqlSession;
    }

    /**
     * 获取mapper
     * @param obj 对象关联
     * @return T
     */
    public  T getMapper(Class<T> obj) {
        return getSqlSession().getMapper(obj);
    }

    public void sqlCommit(){
        this.getSqlSession().commit();
    }

    public void sqlRollBack(){
        this.getSqlSession().rollback();
    }

    public void sqlClose(){
        this.getSqlSession().close();
    }


}
